#include <httpd.h>
#include <string.h>
#include <stdio.h>
#include "apr.h"
#include "apr_buckets.h"
#include "apr_general.h"
#include "apr_lib.h"
#include "apr_strings.h"
#include "apr_hooks.h"
#include "apr_pools.h"
#include "apr_version.h"

#include "http_main.h"
#include "httpd.h"
#include "http_config.h"
#include "http_core.h"
#include "http_main.h"
#include "apr_queue.h"
#include "apr_thread_proc.h"

#include "mod_record_request.h"


static int recorder_post_read(request_rec *r){
  write_message("/tmp/status", "first");
  if(r->unparsed_uri != NULL){
    if(ap_strcmp_match(r->unparsed_uri, "*.do*")==0 &&
         ap_strcmp_match(r->unparsed_uri, "*REQ=*")!=0){
      int len = strlen(r->unparsed_uri);
      if(len >= 4){
        struct timeval t;
	gettimeofday(&t, NULL);
	unsigned long usec = t.tv_usec;
	unsigned long sec = t.tv_sec;

	char *req = apr_psprintf(r->pool, "%i-%i", sec, usec);
	if(r->unparsed_uri[len-1] == 'o' &&
	    r->unparsed_uri[len-2] == 'd' &&
	    r->unparsed_uri[len-3] == '.'){
	  r->unparsed_uri = apr_psprintf(r->pool, "%s?REQ=%s", r->unparsed_uri, req);
	}else{
	  r->unparsed_uri = apr_psprintf(r->pool, "%s&REQ=%s", r->unparsed_uri, req);
	}
	if(r->args==NULL || strlen(r->args) == 0){
	  r->args = apr_psprintf(r->pool, "%sREQ=%s", "", req);
	}else{
	  r->args = apr_psprintf(r->pool, "%s&REQ=%s", r->args, req);
	}
	write_message("/mnt/tmpfs/status", "appended_arg");
	int imgs = get_img_count(r);
	write_message("/mnt/tmpfs/status", "got image count");
	create_new_file(r->pool, req, imgs);
	write_message("/mnt/tmpfs/status", "here");
      }
    }
  }
}

static int recorder_logger(request_rec *r){
  write_message("/tmp/something","something");
  if(r->unparsed_uri != NULL && ap_strcmp_match(r->unparsed_uri, "*.do*")==0){
    int i;
    int arg_index;
    char *args = rindex(r->unparsed_uri, '?');
    char *c_req = (char *)malloc(30*sizeof(char));
    int i_req;
    int req_index;
    int next_index;
    int found_flag = 1;
    next_index = -1;
    if(r->args != NULL){
      for(i=0; i<strlen(args)-5; i++){
        if(found_flag){
	  if(args[i] == 'R' && args[i+1] == 'E' && args[i+2] == 'Q'){
	    req_index=i+4;
	    found_flag=0;
	  }
	}else{
	  if(args[i] == '&'){
	    next_index=i;
	  }
	}
      }
    }
    int req_len = 0;
    char appen[2];
    write_message("/mnt/tmpfs/something", "here");
    if(next_index == -1){
      req_len = strlen(args) - req_index;
    }else{
      req_len = next_index - req_index;
    }
    for(i=0; i<req_len; i++){
      write_message("/mnt/tmpfs/something", apr_psprintf(r->pool, "%i, %i, %i, %i", req_len, i, req_index, strlen(r->args)));
      c_req[i] = args[req_index + i];
    }
    c_req[i] = '\0';
    write_message("/mnt/tmpfs/something", c_req);
    if(decrement_counter(r->pool, c_req) <= 10){
      struct timeval t;
      gettimeofday(&t, NULL);
      unsigned long sec = t.tv_sec;
      unsigned long usec = t.tv_usec;
      delete_file(r->pool, c_req);
      write_message(apr_psprintf(r->pool, "/mnt/tmpfs/fin-%s-%lu-%lu", c_req, sec, usec), "");
    }
  }
}

/*static int recorder_logger(request_rec *r){
  if(r->unparsed_uri != NULL &&
       ap_strcmp_match(r->unparsed_uri, "*.jpg*")==0 ||
       ap_strcmp_match(r->unparsed_uri, "*.gif*")==0){
    int i;
    int arg_index;
    char *args = rindex(r->unparsed_uri, '?');
    char *c_req = (char *)malloc(30*sizeof(char)); 
    int i_req;
    int req_index;
    int next_index;
    int found_flag = 1;
    next_index = -1;
    if(r->args != NULL){
      for(i=0; i<strlen(args)-5; i++){
        if(found_flag){
          if(args[i] == 'R' && args[i+1] == 'E' && args[i+2] == 'Q'){
  	    req_index=i+4;
	    found_flag=0;
	  }
        }else{
          if(args[i] == '&'){
	    next_index=i;
	  }
        }
      }
      int req_len = 0;
      char appen[2];
      write_message("/mnt/tmpfs/something", "here");
      if(next_index == -1){
        req_len = strlen(args) - req_index;
      }else{
        req_len = next_index - req_index;
      }
      for(i=0; i<req_len; i++){
        write_message("/mnt/tmpfs/something", apr_psprintf(r->pool, "%i, %i, %i, %i", req_len, i, req_index, strlen(r->args)));
	c_req[i] = args[req_index + i];
      }
      c_req[i] = '\0';
      write_message("/mnt/tmpfs/something", c_req);
      if(decrement_counter(r->pool, c_req) <= 10){
          struct timeval t;
          gettimeofday(&t, NULL);
	  unsigned long sec = t.tv_sec;
	  unsigned long usec = t.tv_usec;
	  delete_file(r->pool, c_req);
	  write_message(apr_psprintf(r->pool, "/mnt/tmpfs/fin-%s-%lu-%lu", c_req, sec, usec), "");
//        delete_file(r->pool, c_req);
      }
    }
  }
}*/

static int recorder_child_init(apr_pool_t *p, server_rec *s){
  page_info_initialize(p);
}

static void create_new_file(apr_pool_t *p, char *req, int images){
  write_message(apr_psprintf(p, "/mnt/tmpfs/req-%s", req), apr_psprintf(p, "%i", images));

//  FILE *file;
//  file = fopen(get_file_name(p, req), "w+");
//  char *msg = apr_psprintf(p, "%i", images);
//  write_message(apr_psprintf(p, "/tmp/something/%ld", req), msg);
//  fprintf(file, msg);
//  write_message("/tmp/something", apr_psprintf(p, "%i", images));
//  fclose(file);
}

static int decrement_counter(apr_pool_t *p, char *req){
  write_message("/tmp/index", apr_psprintf(p, "%s", req));
  FILE *file;
  file = fopen(get_file_name(p, req), "r");
  int count;
  fscanf(file, "%i", &count);
  count--;
  fclose(file);
  file = fopen(get_file_name(p, req), "w");
  fprintf(file, "%i", count);
  fclose(file);
  return count;
}

static void delete_file(apr_pool_t *p, char *req){
  unlink(get_file_name(p, req));
}

static char *get_file_name(apr_pool_t *p, char *req){
  return apr_psprintf(p, "/mnt/tmpfs/req-%s", req);
}

static void register_hooks(apr_pool_t *pool){
  ap_hook_child_init(recorder_child_init, NULL, NULL, APR_HOOK_LAST);
  ap_hook_post_read_request(recorder_post_read, NULL, NULL, APR_HOOK_LAST);
  ap_hook_log_transaction(recorder_logger, NULL, NULL, APR_HOOK_LAST);
}

module AP_MODULE_DECLARE_DATA recorder_module = {
  STANDARD20_MODULE_STUFF,
  NULL,
  NULL,
  NULL,
  NULL,
  NULL,
  register_hooks
};






static void page_info_initialize(apr_pool_t *p){
 php_pages = (struct php_img*)malloc(PHP_PAGES * sizeof(struct php_img));
 php_pages[0].name = "*admin_confirm.php*";
 php_pages[0].noimages = 5;
 php_pages[1].name = "*admin_request.php*";
 php_pages[1].noimages = 5;
 php_pages[2].name = "*best_sellers.php*";
 php_pages[2].noimages = 4;
 php_pages[3].name = "*buy_confirmed.php*";
 php_pages[3].noimages = 2;
 php_pages[4].name = "*buy_request.php*";
 php_pages[4].noimages = 2;
 php_pages[5].name = "*customer_registration.php*";
 php_pages[5].noimages = 3;
 php_pages[6].name = "*home.php*";
 php_pages[6].noimages = 6;
 php_pages[7].name = "*new_products.php*";
 php_pages[7].noimages = 4;
 php_pages[8].name = "*order_display.php*";
 php_pages[8].noimages = 2;
 php_pages[9].name = "*order_inquiry.php*";
 php_pages[9].noimages = 2;
 php_pages[10].name = "*product_detail.php*";
 php_pages[10].noimages = 4;
 php_pages[11].name = "*search_request.php*";
 php_pages[11].noimages = 3;
 php_pages[12].name = "*search_result.php*";
 php_pages[12].noimages = 3;
 php_pages[13].name = "*shopping_cart.php*";
 php_pages[13].noimages = 4;
}

static void iterate_php(apr_pool_t *p){
  int i;
  for(i=0; i < PHP_PAGES; i++){
    write_message(apr_psprintf(p, "/mnt/tmpfs/%s", php_pages[i].name), "dskfdj");
  }
}

static int get_page_index(apr_pool_t *p, char *name){
  int i;
  for(i=0; i < PHP_PAGES; i++){
    if(ap_strcmp_match(name, php_pages[i].name) == 0){
      return i;
    }
  }
  return -1;
}

static int get_page_from_req(request_rec *r){
  return get_page_index(r->pool, r->unparsed_uri);
}

static int get_img_count(request_rec *r){
  int index;
  index = get_page_from_req(r);
  write_message("/mnt/tmpfs/index", apr_psprintf(r->pool, "%i", index));
  if(index != -1){
    return php_pages[index].noimages;
  }
  return -1;
}




static void write_message(char *file, char *msg){
  FILE *f;
  f = fopen(file, "w+");
  fprintf(f, msg);
  fclose(f);
}
